﻿using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;
using System.Web.Mvc;
using XRM.ActiveDirectoryService;
using XRM.Security.DataAccess.Enums;
using XRM.Security.DataAccess.Models;
using XRM.Security.DataAccess.Repositories.Impl;
using XRM.Security.WebUI.Enums;
using XRM.Security.WebUI.Models.SystemUser;

namespace XRM.Security.WebUI.Controllers
{
    [System.Web.Mvc.Authorize]
    public class SystemUserController : BaseController
    {
        private const string SystemUserTempDataKey = "SystemUserFromAD";

        [System.Web.Mvc.Authorize(Roles = "Administrator, SystemUserEditor")]
        public ActionResult Index()
        { 
            var model = SystemUserRepository.GetAllActive().AsEnumerable().Select( s => new SystemUserModel(s) ).ToList();
            return View(model);
        }

        [System.Web.Mvc.HttpGet]
        [System.Web.Mvc.Authorize(Roles = "Administrator, SystemUserEditor")]
        public ActionResult Edit(int? id)
        {
            if (id != null)
            {
                var systemUser = SystemUserRepository.Get( id );
                if (systemUser == null || systemUser.IsDeleted)
                    throw new HttpResponseException(HttpStatusCode.BadRequest);
                return View(new SystemUserModel( systemUser ));   
            }
            if ( TempData[SystemUserTempDataKey] != null )
            {
                return View( TempData[SystemUserTempDataKey] );
            }
            return RedirectToAction("Index");
        }

        [System.Web.Mvc.HttpPost]
        [System.Web.Mvc.Authorize(Roles = "Administrator, SystemUserEditor")]
        public ActionResult Edit(SystemUserModel model)
        {
            model.RolesFromString(Request.Form["RolesCheck"]);
            if (!ModelState.IsValid)
            {
                ShowAlert(AlertType.Error, GetModelErrors());
                return View(model);
            }
                        
            bool isEdit = model.Id > 0;

            if ( !isEdit && SystemUserRepository.GetByLogin(model.Login) != null )
            {
                ShowAlert(AlertType.Error, string.Format("Пользователь домена с учетной записью '{0}' уже существует", model.Login));
                return View(model);
            }
            
            SystemUser systemUser;
            if ( isEdit )
            {
                systemUser = SystemUserRepository.Get( model.Id );
                if ( systemUser == null )
                    throw new HttpResponseException( HttpStatusCode.BadRequest );
                systemUser.RoleMembers.Clear();
            }
            else
            {
                systemUser = new SystemUser();
            }

            systemUser.Login = model.Login;
            systemUser.FirstName = model.FirstName;
            systemUser.LastName = model.LastName;
            systemUser.MotherName = model.MotherName;
            systemUser.Post = model.Post;
            
            if (model.Roles.Any())
            {
                var roleNames = model.Roles.Select( s => s.RoleName ).ToList();
                using (var roleMemberRepository = new RoleMemberRepository())
                {
                    systemUser.RoleMembers = roleMemberRepository
                        .GetAllRoles().Where( role => roleNames.Contains(role.Name) ).AsEnumerable()
                        .Select( s => new RoleMember {RoleId = s.Id}).ToList();
                }
            }

            if ( isEdit )
            {
                SystemUserRepository.Update( systemUser );
                ShowAlert( AlertType.Success, "Пользователь системы отредактирован успешно" );
            }
            else
            {
                SystemUserRepository.Add( systemUser );
                ShowAlert( AlertType.Success, "Пользователь системы создан успешно" );
            }

            if ( model.Id == UserPrincipal.UserId && !model.Roles.Any( s => s.RoleName == UserRoles.Administrator.ToString() || s.RoleName == UserRoles.SystemUserEditor.ToString() ) )
                return RedirectToAction( "Index", "Home" );

            return RedirectToAction("Index");
        }

        [System.Web.Mvc.Authorize(Roles = "Administrator, SystemUserEditor")]
        public ActionResult Delete(int id)
        {
            var systemUser = SystemUserRepository.Get(id);
            if(systemUser == null)
                throw new HttpResponseException(HttpStatusCode.BadRequest);

            if (RequestRepository.GetAll(x => x.SystemUserId == id && ((x.Status == (int)RequestStatus.InPart) || (x.Status == (int)RequestStatus.InWork))).Any())
            {
                ShowAlert(AlertType.Error, "У данного пользователя есть открытые заявки");
                return RedirectToAction("Index");
            }

            systemUser.RoleMembers.Clear();
            systemUser.IsDeleted = true;
            SystemUserRepository.Update(systemUser);

            ShowAlert(AlertType.Success, "Пользователь системы удален успешно");
            return RedirectToAction("Index");
        }
        
        [System.Web.Mvc.HttpGet]
        [System.Web.Mvc.Authorize(Roles = "Administrator, SystemUserEditor")]
        public ActionResult ADUsersDialog()
        {
            ADUserDialogModel model = new ADUserDialogModel();
            model.DepartmentId = 1;
            model.DepartmentAddressId = 1;
            return View(model);
        }

        [System.Web.Mvc.HttpPost]
        [System.Web.Mvc.Authorize(Roles = "Administrator, SystemUserEditor")]
        public ActionResult ADUsersDialog(ADUserDialogModel model)
        {
            if (model.SubmitAction.Equals("search"))
            {
                if (!ModelState.IsValid)
                {
                    ShowAlert(AlertType.Error, GetModelErrors());
                    return View(model);
                }
                model.ADUserList = ActiveDirectoryService.SearchByFullName( model.SearchString );
                return View(model);
            }

            if (model.SubmitAction.Equals("choise"))
            {
                var adUser = ActiveDirectoryService.SearchByUserName( model.SelectedLogin ).FirstOrDefault();
                if (adUser == null)
                    throw new HttpResponseException(HttpStatusCode.BadRequest);

                var systemUser = new SystemUserModel {
                        Login = adUser.AccountName,
                        FirstName = adUser.FirstName,
                        LastName = adUser.LastName,
                        MotherName = adUser.MiddleName,
                        Post = adUser.Post
                };
                TempData[SystemUserTempDataKey] = systemUser;
                return Json( new {success = true} );
            }
            throw new HttpResponseException(HttpStatusCode.BadRequest);
        }
    }
}
